package com.xzz.service.impl;

import com.xzz.doc.CourseDoc;
import com.xzz.dto.CourseSearchDto;
import com.xzz.respository.CourseEsRepository;
import com.xzz.result.PageList;
import com.xzz.service.ICourseEsService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


@Service
public class CourseEsServiceImpl implements ICourseEsService {

    @Autowired
    private CourseEsRepository courseEsRepository;

    /**
     * 保存需要搜索的课程到ES
     * @param courseDoc
     */
    @Override
    public void saveCourseDoc(CourseDoc courseDoc) {
        //ES就两个方法，一个保存，一个查询
        courseEsRepository.save(courseDoc);
    }

    /**
     * 根据条件，从ES之中去搜索课程
     * @param dto
     * @return PageList
     */
    @Override
    public PageList<CourseDoc> searchCourse(CourseSearchDto dto) {
        //1.1通过构造者，去构造下面所有的条件
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        //2.1 并列的主体条件：分页       .withPageable
        builder.withPageable(PageRequest.of(dto.getPage()-1,dto.getRows()));//分页页码从0开始

        //2.2 并列的主体条件：排序    .withSort   通过SortBuilders构建SortBuilder
        if(!StringUtils.isEmpty(dto.getSortField())){
            String sortField = null;
            switch (dto.getSortField().toLowerCase()){
                case "xl": sortField="saleCount";break;
                case "xp": sortField="onlineTime";break;
                case "pl": sortField="commentCount";break;
                case "jg": sortField="price";break;
                case "rq": sortField="viewCount";break;
            }
            if(!StringUtils.isEmpty(sortField)){
                SortOrder order = SortOrder.DESC;
                if(StringUtils.hasLength(dto.getSortType()) && dto.getSortType().equalsIgnoreCase(SortOrder.ASC.toString())){
                    order =  SortOrder.ASC;
                }
                builder.withSort(SortBuilders.fieldSort(sortField).order(order));
            }
        }

        //2.3 并列的主体条件：查询  .withQuery组合查询bool  通过QueryBuilders构建QueryBuilder
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //2.3.1 must/should 模糊搜索
        if (!StringUtils.isEmpty(dto.getKeyword())){
            boolQuery.must(QueryBuilders.matchQuery("name",dto.getKeyword()));
            //boolQuery.should(QueryBuilders.matchQuery("teacherNames",dto.getKeyword()));
        }
        //2.3.2 filet 过滤等值搜索
        if(dto.getCourseTypeId() != null){
            boolQuery.filter(QueryBuilders.termQuery("courseTypeId",dto.getCourseTypeId()));
        }
        if(!StringUtils.isEmpty(dto.getGradeName())){
            boolQuery.filter(QueryBuilders.termQuery("gradeName",dto.getGradeName()));
        }
        if(!StringUtils.isEmpty(dto.getChargeName())){
            boolQuery.filter(QueryBuilders.termQuery("chargeName",dto.getChargeName()));
        }
        if(dto.getPriceMin() != null){
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(dto.getPriceMin()));
        }
        if(dto.getPriceMax() != null){
            boolQuery.filter(QueryBuilders.rangeQuery("price").lte(dto.getPriceMax()));
        }
        //2.3.4最终形成组合查询
        builder.withQuery(boolQuery);

        //1.2构造者构造条件，完成之后确定构造，就可以得到整个封装好的构造条件
        SearchQuery searchQuery = builder.build();
        //1.3 ES就两个方法，一个保存，一个查询，通过构造条件去查询
        Page<CourseDoc> search = courseEsRepository.search(searchQuery);
        //1.4 返回一个页面数据
        return new PageList<>(search.getTotalElements(),search.getContent());
    }
}
